/***************************************************************************
* sdcdisk_storage.c
*
* Purpose: This is used for USB MSDC to access the storage read/write and others operations
*
* Author:
*
* Date: 2012/06/19
*
* Copyright Generalplus Corp. ALL RIGHTS RESERVED.
*
* Version :
* History :
*
****************************************************************************/
#include "project.h"
#include "stdio.h"
#include "gplib_mm_gplus.h"
#include "drv_l1_cache.h"
#include "drv_l2_usbd_msdc.h"
#include "driver_l1_cfg.h"
#include "drv_l2_sd.h"

#define SD_MSDC_ERR_PRINT	DBG_PRINT
#define SD_MSDC_PRINT(...)

//#define SD_MSDC_PRINT		   DBG_PRINT
/*****************************************************
	Functions API
*****************************************************/

/*****************************************************
	RAMDISK API
*****************************************************/
static INT32S SDCARD_Initial_Storage(void *priv)
{
	INT32U	device_id = (INT32U) priv;
	INT32S	ret = 0;

#ifdef __GNUC__
	SD_MSDC_PRINT("[%s] id=%d\r\n", __FUNCTION__, device_id);
#else
	SD_MSDC_PRINT("[%s] id=%d\r\n", __func__, device_id);
#endif
	ret = drvl2_sd_init(device_id);
	if(ret != 0)
	{
#ifdef __GNUC__
		SD_MSDC_ERR_PRINT("[%s] drvl2_sd_init fail. id=%d ret=%d\r\n", __FUNCTION__, device_id, ret);
#else
		SD_MSDC_ERR_PRINT("[%s] drvl2_sd_init fail. id=%d ret=%d\r\n", __func__, device_id, ret);
#endif
	}

#ifdef __GNUC__
	SD_MSDC_PRINT("[%s] id=%d ret=%d\r\n", __FUNCTION__, device_id, ret);
#else
	SD_MSDC_PRINT("[%s] id=%d ret=%d\r\n", __func__, device_id, ret);
#endif
	return ret;
}

static INT32S SDCARD_Uninitial_Storage(void *priv)
{
	INT32U	device_id = (INT32U) priv;

#ifdef __GNUC__
	SD_MSDC_PRINT("[%s] id=%d\r\n", __FUNCTION__, device_id);
#else
	SD_MSDC_PRINT("[%s] id=%d\r\n", __func__, device_id);
#endif
	drvl2_sd_card_remove(device_id);

#ifdef __GNUC__
	SD_MSDC_PRINT("[%s] id=%d\r\n", __FUNCTION__, device_id);
#else
	SD_MSDC_PRINT("[%s] id=%d\r\n", __func__, device_id);
#endif
	return 0;
}

static void SDCARD_GetDrvInfo_Storage(void *priv, STORAGE_DRV_INFO *info)
{
	INT32U	device_id = (INT32U) priv;

#ifdef __GNUC__
	SD_MSDC_PRINT("[%s] id=%d\r\n", __FUNCTION__, device_id);
#else
	SD_MSDC_PRINT("[%s] id=%d\r\n", __func__, device_id);
#endif
	info->nSectors = drvl2_sd_sector_number_get(device_id);
	info->nBytesPerSector = 512;

#ifdef __GNUC__
	SD_MSDC_PRINT("[%s] id=%d, nSectors=%u\r\n", __FUNCTION__, device_id, info->nSectors);
#else
	SD_MSDC_PRINT("[%s] id=%d, nSectors=%u\r\n", __func__, device_id, info->nSectors);
#endif
}

static INT32S SDCARD_ReadCmdPhase(void *priv, INT32U lba, INT32U seccount)
{
	INT32U	device_id = (INT32U) priv;
	INT32S	ret;

#ifdef __GNUC__
	SD_MSDC_PRINT("[%s] id=%u lba=%u seccount=%u\r\n", __FUNCTION__, device_id, lba, seccount);
#else
	SD_MSDC_PRINT("[%s] id=%u lba=%u seccount=%u\r\n", __func__, device_id, lba, seccount);
#endif
	ret = drvl2_sd_read_start(device_id, lba, seccount);
	if(ret != 0)
	{
#ifdef __GNUC__
		SD_MSDC_ERR_PRINT("[%s] drvl2_sd_read_start fail. id=%d ret=%d\r\n", __FUNCTION__, device_id, ret);
#else
		SD_MSDC_ERR_PRINT("[%s] drvl2_sd_read_start fail. id=%d ret=%d\r\n", __func__, device_id, ret);
#endif
	}

#ifdef __GNUC__
	SD_MSDC_PRINT("[%s] id=%d ret=%d\r\n", __FUNCTION__, device_id, ret);
#else
	SD_MSDC_PRINT("[%s] id=%d ret=%d\r\n", __func__, device_id, ret);
#endif
	return ret;
}

static INT32S SDCARD_ReadSectorDMA(void *priv, INT32U *buf, INT8U ifwait, INT32U seccount)
{
	INT32U	device_id = (INT32U) priv;
	INT32S	ret;

#ifdef __GNUC__
	SD_MSDC_PRINT("[%s] id=%d ifwait=%u seccount=%u\r\n", __FUNCTION__, device_id, ifwait, seccount);
#else
	SD_MSDC_PRINT("[%s] id=%d ifwait=%u seccount=%u\r\n", __func__, device_id, ifwait, seccount);
#endif
	ret = drvl2_sd_read_sector(device_id, buf, seccount, ifwait);
	if(ret != 0)
	{
#ifdef __GNUC__
		SD_MSDC_ERR_PRINT("[%s] drvl2_sd_read_sector fail. id=%d ret=%d\r\n", __FUNCTION__, device_id, ret);
#else
		SD_MSDC_ERR_PRINT("[%s] drvl2_sd_read_sector fail. id=%d ret=%d\r\n", __func__, device_id, ret);
#endif
	}

#ifdef __GNUC__
	SD_MSDC_PRINT("[%s] id=%d ret=%s\r\n", __FUNCTION__, device_id, ret);
#else
	SD_MSDC_PRINT("[%s] id=%d ret=%s\r\n", __func__, device_id, ret);
#endif
	return ret;
}

static INT32S SDCARD_ReadEndCmdPhase(void *priv)
{
	INT32U	device_id = (INT32U) priv;
	INT32S	ret;

#ifdef __GNUC__
	SD_MSDC_PRINT("[%s] id=%d\r\n", __FUNCTION__, device_id);
#else
	SD_MSDC_PRINT("[%s] id=%d\r\n", __func__, device_id);
#endif
	ret = drvl2_sd_read_stop(device_id);
	if(ret != 0)
	{
#ifdef __GNUC__
		SD_MSDC_ERR_PRINT("[%s] drvl2_sd_read_stop fail. id=%d ret=%d\r\n", __FUNCTION__, device_id, ret);
#else
		SD_MSDC_ERR_PRINT("[%s] drvl2_sd_read_stop fail. id=%d ret=%d\r\n", __func__, device_id, ret);
#endif
	}

#ifdef __GNUC__
	SD_MSDC_PRINT("[%s] id=%d ret=%d\r\n", __FUNCTION__, device_id, ret);
#else
	SD_MSDC_PRINT("[%s] id=%d ret=%d\r\n", __func__, device_id, ret);
#endif
	return ret;
}

static INT32S SDCARD_WriteSectorDMA(void *priv, INT32U *buf, INT8U ifwait, INT32U seccount)
{
	INT32U	device_id = (INT32U) priv;
	INT32S	ret;

#ifdef __GNUC__
	SD_MSDC_PRINT("[%s] id=%d ifwait=%u seccount=%u\r\n", __FUNCTION__, device_id, ifwait, seccount);
#else
	SD_MSDC_PRINT("[%s] id=%d ifwait=%u seccount=%u\r\n", __func__, device_id, ifwait, seccount);
#endif
	ret = drvl2_sd_write_sector(device_id, buf, seccount, ifwait);
	if(ret != 0)
	{
#ifdef __GNUC__
		SD_MSDC_ERR_PRINT("[%s] drvl2_sd_write_sector fail. id=%d ret=%d\r\n", __FUNCTION__, device_id, ret);
#else
		SD_MSDC_ERR_PRINT("[%s] drvl2_sd_write_sector fail. id=%d ret=%d\r\n", __func__, device_id, ret);
#endif
	}

#ifdef __GNUC__
	SD_MSDC_PRINT("[%s] id=%d ret=%d\r\n", __FUNCTION__, device_id, ret);
#else
	SD_MSDC_PRINT("[%s] id=%d ret=%d\r\n", __func__, device_id, ret);
#endif
	return ret;
}

static INT32S SDCARD_WriteCmdPhase(void *priv, INT32U lba, INT32U seccount)
{
	INT32U	device_id = (INT32U) priv;
	INT32S	ret;

#ifdef __GNUC__
	SD_MSDC_PRINT("[%s] id=%d lba=%u seccount=%u\r\n", __FUNCTION__, device_id, lba, seccount);
#else
	SD_MSDC_PRINT("[%s] id=%d lba=%u seccount=%u\r\n", __func__, device_id, lba, seccount);
#endif
	ret = drvl2_sd_write_start(device_id, lba, seccount);
	if(ret != 0)
	{
#ifdef __GNUC__
		SD_MSDC_ERR_PRINT("[%s] drvl2_sd_write_start fail. id=%d ret=%d\r\n", __FUNCTION__, device_id, ret);
#else
		SD_MSDC_ERR_PRINT("[%s] drvl2_sd_write_start fail. id=%d ret=%d\r\n", __func__, device_id, ret);
#endif
	}

#ifdef __GNUC__
	SD_MSDC_PRINT("[%s] id=%d ret=%d\r\n", __FUNCTION__, device_id, ret);
#else
	SD_MSDC_PRINT("[%s] id=%d ret=%d\r\n", __func__, device_id, ret);
#endif
	return ret;
}

static INT32S SDCARD_WriteEndCmdPhase(void *priv)
{
	INT32U	device_id = (INT32U) priv;
	INT32S	ret;

#ifdef __GNUC__
	SD_MSDC_PRINT("[%s] id=%d\r\n", __FUNCTION__, device_id);
#else
	SD_MSDC_PRINT("[%s] id=%d\r\n", __func__, device_id);
#endif
	ret = drvl2_sd_write_stop(device_id);
	if(ret != 0)
	{
#ifdef __GNUC__
		SD_MSDC_ERR_PRINT("[%s] drvl2_sd_write_stop fail. id=%d ret=%d\r\n", __FUNCTION__, device_id, ret);
#else
		SD_MSDC_ERR_PRINT("[%s] drvl2_sd_write_stop fail. id=%d ret=%d\r\n", __func__, device_id, ret);
#endif
	}

#ifdef __GNUC__
	SD_MSDC_PRINT("[%s] id=%d ret=%d\r\n", __FUNCTION__, device_id, ret);
#else
	SD_MSDC_PRINT("[%s] id=%d ret=%d\r\n", __func__, device_id, ret);
#endif
	return ret;
}

static INT32S SDCARD_CheckDmaCheckState(void *priv)
{
	//	INT32U	device_id = (INT32U) priv;
#ifdef __GNUC__
	SD_MSDC_PRINT("[%s] id=%d\r\n", __FUNCTION__, device_id);
#else
	SD_MSDC_PRINT("[%s] id=%d\r\n", __func__, device_id);
#endif
	return STORAGE_CHECK_READY;
}

static INT32S SDCARD_Insertion(void *priv)
{
	INT32S	ret = 0;

	//	INT32U	device_id = (INT32U) priv;
	/* 0: inserted, 1: removed */
#ifdef __GNUC__
	SD_MSDC_PRINT("[%s] id=%d ret=%d\r\n", __FUNCTION__, device_id, ret);
#else
	SD_MSDC_PRINT("[%s] id=%d ret=%d\r\n", __func__, device_id, ret);
#endif
	return ret;
}

/* SDC0 disk access functions table */
const MSDC_LUN_STORAGE_DRV	gp_msdc_sd0 =
{
	0,						//private data
	SDCARD_Initial_Storage, //init
	SDCARD_Uninitial_Storage,	//uninit
	SDCARD_Insertion,			//insert event
	SDCARD_GetDrvInfo_Storage,	//get driver info
	SDCARD_ReadCmdPhase,		//read command phase
	SDCARD_ReadSectorDMA,		//read DMA phase
	SDCARD_ReadEndCmdPhase,		//read command end phase
	SDCARD_WriteCmdPhase,		//write command phase
	SDCARD_WriteSectorDMA,		//write DMA phase
	SDCARD_WriteEndCmdPhase,	//write command end phase
	SDCARD_CheckDmaCheckState	//check DMA buffer state
};

/* SDC1 disk access functions table */
const MSDC_LUN_STORAGE_DRV	gp_msdc_sd1 =
{
	((void *) 1),				//private data
	SDCARD_Initial_Storage,		//init
	SDCARD_Uninitial_Storage,	//uninit
	SDCARD_Insertion,			//insert event
	SDCARD_GetDrvInfo_Storage,	//get driver info
	SDCARD_ReadCmdPhase,		//read command phase
	SDCARD_ReadSectorDMA,		//read DMA phase
	SDCARD_ReadEndCmdPhase,		//read command end phase
	SDCARD_WriteCmdPhase,		//write command phase
	SDCARD_WriteSectorDMA,		//write DMA phase
	SDCARD_WriteEndCmdPhase,	//write command end phase
	SDCARD_CheckDmaCheckState	//check DMA buffer state
};
